In [1]:
import mechanize
import json
import pandas as pd
import datetime

In [2]:
# systems I have access to as rsignell@usgs.gov
d={}
d['signell']='15610'
d['buesseler']='13942'
d['lindell']='14479'
d['mcgillicuddy']='16327'

# my micro inverter ids
micro={}
micro['southeast']= ['395311', '395314', '395315', '395313', '395320', '395309', '395310']
micro['southwest']= ['395321', '395312', '395318', '395319', '395317', '395316']

In [3]:
login_url='https://enlighten.enphaseenergy.com/login'
username='rsignell@usgs.gov'
password='4U10PXWU55'

In [4]:
# read the login form
response = mechanize.urlopen(login_url)
forms = mechanize.ParseResponse(response, backwards_compat=False)
form = forms[0]
print form


<POST https://enlighten.enphaseenergy.com/login/login application/x-www-form-urlencoded
  <HiddenControl(utf8=&#x2713;) (readonly)>
  <HiddenControl(authenticity_token=UO1xEPo5HE8VjZPsXLoBWVS+rqABPDiejTlKVxCpU7I=) (readonly)>
  <TextControl(user[email]=)>
  <PasswordControl(user[password]=)>
  <SubmitControl(commit=Sign In) (readonly)>>

In [5]:
# fill in the login form
br=mechanize.Browser()
br.open(login_url)
br.select_form(nr=0)
br.set_all_readonly(False)
br['user[email]']=username
br['user[password]']=password
br['authenticity_token']=form['authenticity_token']
br['commit']=form['commit']
br['utf8']=form['utf8']
br.submit();

In [12]:
# retrieve the JSON data and return as Pandas Series
# https://enlighten.enphaseenergy.com/systems/15610/inverters/405150/time_series_x?&date=2013-11-19&stat=POWR%2CDCV%2CDCA%2CACV%2CACHZ%2CTMPI
def get_micro_data(system='15610', micro_inverters=['395315']):
    
    def get_data(system,inverter):
#        url='https://enlighten.enphaseenergy.com/systems/%s/devices/%s/graph_widget.json?timeframe=recent' % (system, inverter)
        url='https://enlighten.enphaseenergy.com/systems/%s/inverters/%s/time_series_x?&date=2013-11-19&stat=POWR' % (system, inverter)
        tmp_file = br.retrieve(url)[0]
        print tmp_file
        json_data=open(tmp_file)
        data = json.load(json_data)
        u=array(data['data_sets'][0]['data'])
        return u
    
    first = True
    for inverter in micro_inverters:
        if first:
            u = get_data(system, inverter)
            dn=[datetime.datetime.fromtimestamp(time) for time in u[:,0]]
            df=pd.DataFrame(u[:,1],index=dn, columns=[inverter])
            first = False
        else:
            u = get_data(system, inverter)
            df[inverter]=u[:,1]
    return df

In [13]:
df_east = get_micro_data(system=d['signell'],micro_inverters=micro['southeast'])


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-13-82e2989702bf> in <module>()
----> 1 df_east = get_micro_data(system=d['signell'],micro_inverters=micro['southeast'])

<ipython-input-12-f755825fbc20> in get_micro_data(system, micro_inverters)
     16     for inverter in micro_inverters:
     17         if first:
---> 18             u = get_data(system, inverter)
     19             dn=[datetime.datetime.fromtimestamp(time) for time in u[:,0]]
     20             df=pd.DataFrame(u[:,1],index=dn, columns=[inverter])

<ipython-input-12-f755825fbc20> in get_data(system, inverter)
      9         print tmp_file
     10         json_data=open(tmp_file)
---> 11         data = json.load(json_data)
     12         u=array(data['data_sets'][0]['data'])
     13         return u

C:\Users\rsignell\AppData\Local\Enthought\Canopy32\App\appdata\canopy-1.0.3.1262.win-x86\lib\json\__init__.pyc in load(fp, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    276         parse_float=parse_float, parse_int=parse_int,
    277         parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
--> 278         **kw)
    279 
    280 

C:\Users\rsignell\AppData\Local\Enthought\Canopy32\App\appdata\canopy-1.0.3.1262.win-x86\lib\json\__init__.pyc in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    324             parse_int is None and parse_float is None and
    325             parse_constant is None and object_pairs_hook is None and not kw):
--> 326         return _default_decoder.decode(s)
    327     if cls is None:
    328         cls = JSONDecoder

C:\Users\rsignell\AppData\Local\Enthought\Canopy32\App\appdata\canopy-1.0.3.1262.win-x86\lib\json\decoder.pyc in decode(self, s, _w)
    364 
    365         """
--> 366         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    367         end = _w(s, end).end()
    368         if end != len(s):

C:\Users\rsignell\AppData\Local\Enthought\Canopy32\App\appdata\canopy-1.0.3.1262.win-x86\lib\json\decoder.pyc in raw_decode(self, s, idx)
    382             obj, end = self.scan_once(s, idx)
    383         except StopIteration:
--> 384             raise ValueError("No JSON object could be decoded")
    385         return obj, end

ValueError: No JSON object could be decoded
c:\users\rsignell\appdata\local\temp\2\tmpul2pnm

In [ ]:
df_east.plot(figsize=(16,4),grid=True,title='Southeast Panels');

In [ ]:
df_west = get_micro_data(system=d['signell'],micro_inverters=micro['southwest'])

In [ ]:
df_west.plot(figsize=(16,4),grid=True,title='Southwest Panels');

In [ ]:
dfwm=df_west.median(axis=1)

In [ ]:
dfem=df_east.median(axis=1)

In [ ]:
dfcomp=pd.concat([dfem, dfwm],axis=1)

In [ ]:
dfcomp.plot(figsize=(16,4),grid=True,title='Southeast/Southwest Panel comparison');

In the plot above, you can see that the southeast panels produce more power earlier in the day, and southwest panels produce more power later in the day, as you would expect.


In [ ]:
df_diff = dfcomp[0]-dfcomp[1]
df_diff.plot(figsize=(16,4),grid=True,title='Southeast - Southwest Panels');

In [ ]:
df_diff = (dfcomp[0]-dfcomp[1])/(dfcomp[0]+dfcomp[1])
df_diff.plot(figsize=(16,4),grid=True,title='fraction difference (SE-SW)/(SW+SE)');

In [ ]: